﻿using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.WsFederation;
using Microsoft.Owin.Security.DataProtection;
using Owin;
using System;
using CloudStorageLight.Web.Models;
using ElCamino.AspNet.Identity.AzureTable;
using CloudStorageLight.Core;
using Microsoft.Owin.Security.OpenIdConnect;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Web;
using System.Threading.Tasks;
using System.IdentityModel.Claims;
using System.Web.Security;
using Microsoft.Owin.Security;

namespace CloudStorageLight.Web
{
    public partial class Startup
    {
        private static string clientId = SystemSettings.Instance.MicrosoftAccountClientId;
        private static string appKey = SystemSettings.Instance.MicrosoftAccountClientSecret;
        public static readonly string Authority = "https://login.microsoftonline.com/" + SystemSettings.Instance.IdaTenantId;

        private static string realm = SystemSettings.Instance.IdaRealm;
        private static string adfs = SystemSettings.Instance.IdaAdfs;
        private static string metadata = string.Format("https://{0}/federationmetadata/2007-06/federationmetadata.xml", adfs);
        
        // 認証設定の詳細については、http://go.microsoft.com/fwlink/?LinkId=301864 を参照してください
        public void ConfigureAuth(IAppBuilder app)
        {

            switch (SystemSettings.Instance.AuthMode ?? "")
            {
                case "":
                case "UserPassword":
                    // リクエストあたり 1 インスタンスのみを使用するように DB コンテキストとユーザー マネージャーを設定します
                    app.CreatePerOwinContext(ApplicationDbContext.Create);
                    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

                    // アプリケーションが Cookie を使用して、サインインしたユーザーの情報を格納できるようにします
                    // また、サードパーティのログイン プロバイダーを使用してログインするユーザーに関する情報を、Cookie を使用して一時的に保存できるようにします
                    // サインイン Cookie の設定
                    app.UseCookieAuthentication(new CookieAuthenticationOptions
                    {
                        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                        CookieName = SystemSettings.Instance.ApplicationCookieName ?? ".ASPXAUTH",
                        LoginPath = new PathString("/Account/Login"),
                        Provider = new CookieAuthenticationProvider
                        {
                            //OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                            //    validateInterval: TimeSpan.FromMinutes(30),
                            //    regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                        }
                    });


                    if (!string.IsNullOrEmpty(SystemSettings.Instance.MicrosoftAccountClientId))
                    {
                        app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
                        app.UseMicrosoftAccountAuthentication(
                            clientId: SystemSettings.Instance.MicrosoftAccountClientId,
                            clientSecret: SystemSettings.Instance.MicrosoftAccountClientSecret);
                    }

                    break;
                case "ADFS":
                    if (!string.IsNullOrEmpty(realm) &&!string.IsNullOrEmpty(adfs))
                    {
                        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

                        app.UseCookieAuthentication(new CookieAuthenticationOptions());

                        app.UseWsFederationAuthentication(
                            new WsFederationAuthenticationOptions
                            {
                                Wtrealm = realm,
                                MetadataAddress = metadata,

                            });
                    }
                    break;
                case "AzureAD":

                    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

                    app.UseCookieAuthentication(new CookieAuthenticationOptions());

                    app.UseOpenIdConnectAuthentication(
                        new OpenIdConnectAuthenticationOptions
                        {
                            ClientId = clientId,
                            Authority = Authority,
                            PostLogoutRedirectUri = SystemSettings.Instance.IdaRealm,

                            Notifications = new OpenIdConnectAuthenticationNotifications()
                            {
                        // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away.
                        AuthorizationCodeReceived = (context) =>
                                {
                                    string graphResourceId = "https://graph.windows.net";
                                    var code = context.Code;
                                    ClientCredential credential = new ClientCredential(clientId, appKey);
                                    string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value;
                                    AuthenticationContext authContext = new AuthenticationContext(Authority);
                                    AuthenticationResult result = authContext.AcquireTokenByAuthorizationCodeAsync(
                                    code, new Uri(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Path)), credential, graphResourceId).Result;

                                    return Task.FromResult(0);
                                }
                            }
                        });

                    break;

                default:
                    throw new InvalidProgramException("invlaid AuthMode");
            }

        }
    }
}